<%
'######################################################################
'## ab.cache.asp
'## -------------------------------------------------------------------
'## Feature     :   AspBox Cache Class
'## Version     :   v1.0
'## Author      :   Lajox(lajox@19www.com)
'## Update Date :   2013/12/05 14:00
'## Description :   Save and Get Cache With AspBox
'######################################################################

Class Cls_AB_Cache

	Public Items, CountEnabled, Expires, FileType
	Private s_path, b_fsoOn

	Private Sub Class_Initialize
		Set Items = Server.CreateObject(AB.dictName)
		s_path = Server.MapPath("/_cache") & "\"
		CountEnabled = True
		Expires = 5
		FileType = ".cache"
		AB.Error(91) = "当前对象不允许缓存到内存缓存"
		AB.Error(92) = "缓存内容或文件不存在"
		AB.Error(93) = "当前内容不允许缓存到文件缓存"
		If TypeName(AB.Fso) = "Cls_AB_Fso" Then
			b_fsoOn = True
		Else
			AB.Use "Fso"
			b_fsoOn = False
		End If
	End Sub

	Private Sub Class_Terminate
		If Not b_fsoOn Then
			'Set AB.Fso = New Cls_AB_obj
			Set AB.Fso = Nothing
		End If
		Set Items = Nothing
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.New 方法
	'# @syntax: Set myCacheObj = AB.Cache.New
	'# @return: Object (ASP对象)
	'# @dowhat: 建立缓存对象, 创建一个 AspBox_cache 对象
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# 这个例子创建了一个缓存对象并重设了缓存路径
	'# Dim myCacheObj : Set myCacheObj = AB.Cache.New 	'创建缓存对象
	'# myCacheObj.SavePath = "../pageCache/" 			'设置缓存路径
	'------------------------------------------------------------------------------------------

	Public Function [New]()
		Set [New] = New Cls_AB_Cache
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Cache.Expires 属性
	'# @syntax: AB.Cache.Expires[ = time]
	'# @return: Datetime (时间日期) 或 Numeric (数值)
	'# 			返回Numeric(数值)表示缓存的存活周期，单位为分钟；返回Datetime(时间日期)表示缓存的具体过期时间。
	'# @dowhat: 设置缓存过期时间，此属性可读可写
	'# 			通过此方法设置缓存过期时间，当time为0时，表示缓存永不过期，不设置则默认为5分钟。
	'# 			该方法仅对此代码下面的被Ready的缓存有效。
	'# 			也可以单独为某个缓存设置过期时间，具体见示例。
	'--DESC------------------------------------------------------------------------------------
	'# @param: time(可选) Datetime (时间日期) 或 Numeric (数值)
	'# 缓存的过期时间，可使用分钟数表示存活周期，也可使用具体的时间设置固定的过期时间，
	'# 当time为0时，表示缓存永不过期。
	'--DEMO------------------------------------------------------------------------------------
	'# '缓存两周内有效
	'# AB.Cache.Expires = 60*24*14
	'# '缓存"maya"将于2012年12月22日过期
	'# AB.Cache("maya").Expires = "2012-12-22"
	'------------------------------------------------------------------------------------------

	'------------------------------------------------------------------------------------------
	'# AB.Cache.FileType 属性
	'# @syntax: AB.Cache.FileType[ = fileType]
	'# @return: String (字符串) 查询此属性时，返回文件缓存的后缀名
	'# @dowhat: 此属性用于查询或者设置文件缓存保持为文件时的后缀，默认值为“.cache”。也可以对具体缓存设置后缀
	'--DESC------------------------------------------------------------------------------------
	'# @param: fileType(可选) String (字符串) 设置文件后缀，格式".后缀名"
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache.FileType = ".tmp"
	'# AB.Cache("test1") = "缓存数据1"
	'# AB.Cache("test1").Save
	'# '将test1缓存保持为文件缓存。在文件缓存目录中将生成.tmp后缀的文件缓存
	'------------------------------------------------------------------------------------------

	'------------------------------------------------------------------------------------------
	'# AB.Cache.Count 属性(只读)
	'# @syntax: count = AB.Cache.Count
	'# @return: Integer (整数) 返回当前所有缓存数量。当AB.Cache.CountEnabled 属性为False时，返回值为-1
	'# @dowhat: 查询当前所有缓存数量，此属性只读
	'# 			只有在缓存配置属性：AB.Cache.CountEnabled 为 True 时，才统计保存的缓存数量。
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Use "Cache"
	'#
	'# '保存两个文件缓存
	'# AB.Cache("test1")="1"
	'# AB.Cache("test1").Save
	'# AB.Cache("test2")="2"
	'# AB.Cache("test2").Save
	'#
	'# '查询缓存数量
	'# AB.C.PrintCn AB.Cache.Count '输出结果：1
	'#
	'# '不统计缓存数量
	'# AB.Cache.CountEnabled = False
	'# AB.C.PrintCn AB.Cache.Count '输出结果：-1
	'------------------------------------------------------------------------------------------

	Public Property Get Count
		Count = AB.C.IIF(CountEnabled,AB_Cache_Count,-1)
	End Property

	'------------------------------------------------------------------------------------------
	'# AB.Cache.SavePath 属性
	'# @syntax: AB.Cache.FileType[ = fielType]
	'# @return: String (字符串) 查询此属性时，返回存储文件缓存目录的绝对路径
	'# @dowhat: 文件缓存在站点上的存储目录，此属性可读可写
	'# 文件缓存是缓存的一种类型。该属性用于设置和查询文件缓存所存储的目录。如果不设置此属性，则默认为"/_cache"。
	'--DESC------------------------------------------------------------------------------------
	'# @param: path(可选) String (字符串)
	'# 可选，文件夹路径，可以是相对路径、站点绝对路径(以/开头)和硬盘绝对路径(以"盘符:\"开头)，
	'# 默认为网站根目录下的_cache目录
	'--DEMO------------------------------------------------------------------------------------
	'# '设置文件缓存存储目录
	'# AB.Use "Cache"
	'# AB.cache.SavePath = "/myCache"
	'# '获取文件缓存存储目录
	'# Dim path: path = AB.cache.SavePath
	'# AB.C.Print path '输出的结果(假设网站路径：D:\Web\)是： D:\Web\myCache\
	'------------------------------------------------------------------------------------------

	Public Property Let SavePath(ByVal s)
		If Not Instr(s,":") = 2 Then s = Server.MapPath(s)
		If Right(s,1) <> "\" Then s = s & "\"
		s_path = s
	End Property

	Public Property Get SavePath()
		SavePath = s_path
	End Property

	'------------------------------------------------------------------------------------------
	'# AB.Cache.Item 属性
	'# @syntax: AB.Cache.Item(cacheName)[ = value]
	'# @alias:  AB.Cache(cacheName)[ = value]
	'# @return: Object (ASP对象) 或 Recordset (记录集对象) 或 String (字符串)
	'# 			文件缓存时，赋值/返回为String(字符串)类型或Recordset(记录集对象)；使用内存缓存时请参考：AB.C.SetApp。
	'# @dowhat: 存储和取回缓存
	'# 缓存类使用2种方式保存缓存：
	'# 1.文件缓存，将缓存的值保存为文件，目前支持String(字符串)类型和Recordset(记录集对象)（相当于Recordset.Save）
	'# 存储方法为: AB.Cache("CacheName").Save 或 AB.Cache.SaveAll
	'# 2.内存缓存，将缓存保存到内存，请参考：AB.C.SetApp。内存缓 Recordset 对象时会自动转换为数组。
	'# 存储方法为: AB.Cache("CacheName").SaveApp 或 AB.Cache.SaveAppAll
	'# 取出：Value = AB.Cache("CacheName") ，如果同时使用了内存和文件缓存，则优先读取内存中的值。
	'--DESC------------------------------------------------------------------------------------
	'# @param: cacheName String (字符串)
	'# 缓存名称，同时也用于保存文件缓存时的文件名，不能包含 \*?"<>| 等符号，但可以用 / 表示保存文件缓存时的目录结构
	'# @param: value(可选) Object (ASP对象) 或 Recordset (记录集对象) 或 String (字符串)
	'# 要保存的缓存值。如果保存为文件缓存，则此项值可以是字符串和记录集；
	'# 如果保存为内存缓存，则可以是字符串、记录集或者Dictionary等其它ASP对象
	'--DEMO------------------------------------------------------------------------------------
	'# '###下面的例子说明了如何存储和取出缓存:
	'# AB.Cache.Expires = 60		'设置缓存过期的时间，60表示60分钟
	'# If AB.Cache("myCache").Ready Then	'如果缓存有效
	'# 	AB.C.Print AB.C.Cache("myCache") 	'输出缓存
	'# Else
	'# 	AB.Cache("myCache") = "要缓存的文本"
	'# 	AB.Cache("myCache").Save 	'保存缓存
	'# End If
	'#
	'# '###以下代码缓存某个 Recordset 对象，而不必每次查询数据库
	'# If AB.Cache("rs").Ready Then
	'# 	Set rs = AB.Cache("rs")	'还原记录集
	'# Else
	'# 	Set rs = AB.DB.GR("table","","")
	'# 	AB.Cache("rs") = rs
	'# 	AB.Cache("rs").Save		'保存记录集到缓存
	'# End If
	'# '接下来像平时一样输出数据吧
	'# Do While Not rs.Eof
	'# 	AB.C.Print rs(0)
	'# 	rs.Movenext
	'# Loop
	'------------------------------------------------------------------------------------------

	Public Property Let Item(ByVal p, ByVal v)
		If IsNull(p) Then p = ""
		If Not IsObject(Items(p)) Then
			Set Items(p) = New Cls_AB_Cache_Info
			Items(p).CountEnabled = CountEnabled
			Items(p).Expires = Expires
			Items(p).FileType = FileType
		End If
		Items(p).Name = p
		Items(p).Value = v
		Items(p).SavePath = s_path
	End Property

	Public Default Property Get Item(ByVal p)
		If Not IsObject(Items(p)) Then
			Set Items(p) = New Cls_AB_Cache_Info
			Items(p).Name = p
			Items(p).SavePath = s_path
			Items(p).CountEnabled = CountEnabled
			Items(p).Expires = Expires
			Items(p).FileType = FileType
		End If
		Set Item = Items(p)
	End Property

	'------------------------------------------------------------------------------------------
	'# AB.Cache.Get 方法
	'# @syntax: AB.Cache.Get(cacheName)
	'# @alias:  AB.Cache(cacheName).Value 或 AB.Cache.Item(cacheName).Value
	'# @return: Object (ASP对象) 或 Recordset (记录集对象) 或 String (字符串)
	'# @dowhat: 获取缓存数据(优先读取内容缓存数据)
	'# 			若同时存在名称为 cacheName 的内容缓存 和 名称为 cacheName 的文件缓存，则优先读取内容缓存数据
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache.Save("test") '等同于：AB.Cache("test").Save
	'# AB.C.PrintCn AB.Cache.Get("test")
	'# AB.C.PrintCn AB.Cache("test").Value
	'------------------------------------------------------------------------------------------

	Public Function [Get](ByVal s)
		Dim temp,f : f = s
		If Items.Exists(f) Then
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then temp = Items(f).Value
		End IF
		[Get] = temp
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Cache.Save 方法
	'# @syntax: AB.Cache.Save(cacheName)
	'# @alias:  AB.Cache(cacheName).Save 或 AB.Cache.Item(cacheName).Save
	'# @return: 无返回值
	'# @dowhat: 保存文件缓存
	'# 将名称为 cacheName 的缓存数据保存为文件缓存，可以各种格式数据，如保存记录对象。
	'# 无法保存时抛出错误：“当前内容不允许缓存到文件缓存”
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache.Save("test") '等同于：AB.Cache("test").Save
	'# AB.C.Print AB.Cache("test")
	'# AB.Trace AB.Cache("test").Value
	'------------------------------------------------------------------------------------------

	Public Sub Save(ByVal s)
		Dim f : f = s
		If Items.Exists(f) Then
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then Items(f).Save
		End IF
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.SaveAll 方法
	'# @syntax: AB.Cache.SaveAll
	'# @return: 无返回值
	'# @dowhat: 所有缓存数据保存为文件缓存
	'# 将当前所有的缓存数据保存为文件缓存，能够保存为文件缓存的数据类型可以是字符串(String)或者记录集(Recordset)
	'# 文件保存的位置将由 AB.Cache.SavePath 属性和 cacheName 中的路径信息共同组成，扩展名由 AB.Cache.FileType 属性决定。
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test1") = "缓存数据1"
	'# AB.Cache("test2") = "缓存数据2"
	'# AB.Cache.SaveAll	 '保存名为 test1 和 test2 的缓存
	'# AB.C.PrintCn AB.Cache("test1")
	'# AB.C.PrintCn AB.Cache("test2")
	'# AB.Trace Array(AB.Cache("test1").Value,AB.Cache("test2").Value)
	'------------------------------------------------------------------------------------------

	Public Sub SaveAll
		Dim f
		For Each f In Items
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then Items(f).Save
		Next
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.SaveApp 方法
	'# @syntax: AB.Cache.SaveApp(cacheName)
	'# @alias:  AB.Cache(cacheName).SaveApp 或 AB.Cache.Item(cacheName).SaveApp
	'# @return: 无返回值
	'# @dowhat: 保存内存缓存
	'# 将名称为 cacheName 的缓存数据保存为内存缓存，可以各种格式数据，保存记录对象时会自动转为二维数组。
	'# 无法保存时抛出错误：“当前对象不允许缓存到内存缓存”
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache.SaveApp("test") '等同于：AB.Cache("test").SaveApp
	'# AB.C.Print AB.Cache("test")
	'# AB.Trace AB.Cache("test").Value
	'------------------------------------------------------------------------------------------

	Public Sub SaveApp(ByVal s)
		Dim f : f = s
		If Items.Exists(f) Then
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then Items(f).SaveApp
		End IF
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.SaveAppAll 方法
	'# @syntax: AB.Cache.SaveAppAll
	'# @return: 无返回值
	'# @dowhat: 所有缓存数据保存为内存缓存
	'# 			将当前所有的缓存数据保存为内存缓存，可以保存任意值，保存记录对象时会自动转为二维数组
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test1") = "缓存数据1"
	'# AB.Cache("test2") = "缓存数据2"
	'# AB.Cache.SaveAppAll	 '保存名为 test1 和 test2 的缓存到内存
	'# AB.C.PrintCn AB.Cache("test1")
	'# AB.C.PrintCn AB.Cache("test2")
	'# AB.Trace Array(AB.Cache("test1").Value,AB.Cache("test2").Value)
	'------------------------------------------------------------------------------------------

	Public Sub SaveAppAll
		Dim f
		For Each f In Items
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then Items(f).SaveApp
		Next
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.Remove 方法
	'# @syntax: AB.Cache.Remove(cacheName)
	'# @alias:  AB.Cache(cacheName).Remove 或 AB.Cache.Item(cacheName).Remove
	'# @return: 无返回值
	'# @dowhat: 删除文件缓存
	'# 将名称为 cacheName 的文件缓存数据删除。
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache("test").Save
	'# AB.Cache.Remove("test") '等同于：AB.Cache("test").Remove
	'------------------------------------------------------------------------------------------

	Public Sub Remove(ByVal s)
		Dim f : f = s
		If Items.Exists(f) Then
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then Items(f).Remove
			'Items.Remove(f)
		End IF
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.RemoveAll 方法
	'# @syntax: AB.Cache.RemoveAll
	'# @return: 无返回值
	'# @dowhat: 所有文件缓存数据删除
	'# 			将当前所有的保存到文件的缓存数据删除
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test1") = "缓存数据1"
	'# AB.Cache("test2") = "缓存数据2"
	'# AB.Cache.SaveAll	 '保存名为 test1 和 test2 的缓存到内存
	'# AB.Cache.RemoveAll	 '将名为 test1 和 test2 的缓存从文件中删除
	'------------------------------------------------------------------------------------------

	Public Sub RemoveAll
		Dim f
		For Each f In Items
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then Items(f).Remove
			'Items.Remove(f)
		Next
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.RemoveApp 方法
	'# @syntax: AB.Cache.RemoveApp(cacheName)
	'# @alias:  AB.Cache(cacheName).RemoveApp 或 AB.Cache.Item(cacheName).RemoveApp
	'# @return: 无返回值
	'# @dowhat: 删除内容缓存
	'# 将名称为 cacheName 的内容缓存数据删除。
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache("test").SaveApp
	'# AB.Cache.RemoveApp("test") '等同于：AB.Cache("test").RemoveApp
	'------------------------------------------------------------------------------------------

	Public Sub RemoveApp(ByVal s)
		Dim f : f = s
		If Items.Exists(f) Then
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then Items(f).RemoveApp
			'Items.Remove(f)
		End IF
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.RemoveAppAll 方法
	'# @syntax: AB.Cache.RemoveAppAll
	'# @return: 无返回值
	'# @dowhat: 所有内存缓存数据删除
	'# 			将当前所有的保存到内存的缓存数据删除
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test1") = "缓存数据1"
	'# AB.Cache("test2") = "缓存数据2"
	'# AB.Cache.SaveAppAll	 '保存名为 test1 和 test2 的缓存到内存
	'# AB.Cache.RemoveAppAll	 '将名为 test1 和 test2 的缓存从内存中删除
	'------------------------------------------------------------------------------------------

	Public Sub RemoveAppAll
		Dim f
		For Each f In Items
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then Items(f).RemoveApp
			'Items.Remove(f)
		Next
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.Del 方法
	'# @syntax: AB.Cache.Del(cacheName)
	'# @alias:  AB.Cache(cacheName).Del 或 AB.Cache.Item(cacheName).Del
	'# @return: 无返回值
	'# @dowhat: 删除内容缓存
	'# 将名称为 cacheName 的内容缓存数据删除。
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据1"
	'# AB.Cache("test").SaveApp '存为内容缓存
	'# AB.Cache.Del("test") '等同于：AB.Cache("test").Del
	'# AB.Cache("test") = "缓存数据2"
	'# AB.Cache("test").Save '存为文件缓存
	'# If AB.Cache("test").Ready Then
	'# 	AB.Trace AB.Cache("test")
	'# End If
	'------------------------------------------------------------------------------------------

	Public Sub Del(ByVal s)
		Dim f : f = s
		If Items.Exists(f) Then
			If Lcase(TypeName(Items(f))) = "cls_ab_cache_info" Then
				Items(f).Remove
				Items(f).RemoveApp
			End If
		End IF
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache.Clear 方法
	'# @syntax: AB.Cache.Clear
	'# @return: 无返回值
	'# @dowhat: 将所有缓存数据删除（包括内存缓存和文件缓存）
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test1") = "缓存数据1"
	'# AB.Cache("test2") = "缓存数据2"
	'# AB.Cache.SaveAll	 	'保存名为 test1 和 test2 的缓存保存到文件
	'# AB.Cache("test3") = "缓存数据3"
	'# AB.Cache("test4") = "缓存数据4"
	'# AB.Cache.SaveAppAll	 '保存名为 test3 和 test4 的缓存保存到内存
	'# AB.Cache.Clear	 '将所有缓存数据删除
	'------------------------------------------------------------------------------------------

	Public Sub [Clear]
		RemoveAll
		RemoveAppAll
		AB.C.RemoveApp "AB_Cache_Count"
	End Sub

End Class

Function AB_Cache_Count()
	AB_Cache_Count = 0
	Dim n : n = AB.C.GetApp("AB_Cache_Count")
	If IsArray(n) Then
		If Ubound(n) = 1 Then AB_Cache_Count = n(0)
	End If
End Function

Function AB_CacheCount_Change(ByVal a, ByVal t)
	Dim n : n = AB.C.GetApp("AB_Cache_Count")
	If isArray(n) Then
		If Ubound(n) = 1 Then
			If TypeName(n(1)) = "Dictionary" Then
				If t = 1 Then n(1)(a) = a
				If t = -1 Then
					If n(1).Exists(a) Then n(1).Remove(a)
				End If
				AB.C.SetApp "AB_Cache_Count", Array(n(1).Count,n(1))
			End If
		End If
	Else
		Dim dic : Set dic = Server.CreateObject(AB.dictName)
		If t = 1 Then dic(a) = a
		AB.C.SetApp "AB_Cache_Count", Array(AB.C.IIF(t=1,1,0),dic)
	End If
End Function

class Cls_AB_Cache_Info

	Public SavePath, [Name], CountEnabled, FileType
	Private i_exp, d_exp, o_value

	Private Sub Class_Initialize
		i_exp = 5
		d_exp = ""
	End Sub

	Private Sub Class_Terminate
		If IsObject(o_value) Then Set o_value = Nothing
	End Sub

	Public Property Let Expires(ByVal i)
		If isDate(i) Then
			d_exp = CDate(i)
		ElseIf isNumeric(i) Then
			If i>0 Then
				i_exp = i
			ElseIf i=0 Then
				i_exp = 60*24*365*99
			End If
		End If
	End Property

	Public Property Get Expires()
		Expires = AB.C.IfHas(d_exp, i_exp)
	End Property

	Public Property Let [Value](ByVal s)
		If IsObject(s) Then
			Select Case TypeName(s)
				Case "Recordset"
					Set o_value = s.Clone
				Case Else
					Set o_value = s
			End Select
		Else
			o_value = s
		End If
	End Property

	Public Default Property Get [Value]()
		On Error Resume Next
		Dim app : app = AB.C.GetApp(Me.Name)
		If IsArray(app) Then
			If UBound(app) = 1 Then
				If IsDate(app(0)) Then
					If IsObject(app(1)) Then
						Set [Value] = app(1)
						Exit Property
					Else
						[Value] = app(1)
						If AB.C.Has([Value]) Then Exit Property
					End If
				End If
			End If
		End If
		If AB.Fso.IsFile(FilePath) Then
			Dim rs
			set rs = Server.CreateObject("Adodb.Recordset")
			rs.Open FilePath
			If Err.Number <> 0 Then
				Err.Clear
				[Value] = AB.Fso.Read(FilePath)
			Else
				Set [Value] = rs
			End If
		Else
			AB.Error.Msg = "("""&AB.C.HtmlEncode(Me.Name)&""")" : AB.Error.Raise 92
		End If
		On Error Goto 0
	End Property

	'------------------------------------------------------------------------------------------
	'# AB.Cache(cacheName).SaveApp 方法
	'# @syntax: AB.Cache(cacheName).SaveApp
	'# @alias:  AB.Cache.Item(cacheName).SaveApp
	'# @return: 无返回值
	'# @dowhat: 保存内存缓存
	'# 将名称为 cacheName 的缓存数据保存为内存缓存，可以各种格式数据，保存记录对象时会自动转为二维数组。
	'# 无法保存时抛出错误：“当前对象不允许缓存到内存缓存”
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache("test").SaveApp
	'------------------------------------------------------------------------------------------

	Public Sub SaveApp
		Dim appArr(1) : appArr(0) = Now()
		If IsObject(o_value) Then
			Select Case TypeName(o_value)
				Case "Dictionary"
					Set appArr(1) = o_value
				Case "Recordset"
					appArr(1) = o_value.GetRows(-1)
				Case Else
					AB.Error.Msg = "("""&AB.C.HtmlEncode(Me.Name)&" &gt; "&TypeName(o_value)&""")" : AB.Error.Raise 91
			End Select
		Else
			appArr(1) = o_value
		End If
		AB.C.SetApp Me.Name, appArr
		If CountEnabled Then AB_CacheCount_Change Me.Name, 1
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache(cacheName).Save 方法
	'# @syntax: AB.Cache(cacheName).Save
	'# @alias:  AB.Cache.Item(cacheName).Save
	'# @return: 无返回值
	'# @dowhat: 保存文件缓存
	'# 将名称为 cacheName 的缓存数据保存为文件缓存，可以各种格式数据，如保存记录对象。
	'# 无法保存时抛出错误：“当前内容不允许缓存到文件缓存”
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache("test").Save
	'------------------------------------------------------------------------------------------

	Public Sub Save
		Select Case TypeName(o_value)
			Case "Recordset"
				AB.Fso.CreateFile FilePath, "rs"
				AB.Fso.DelFile FilePath
				o_value.Save FilePath, adPersistXML
				If CountEnabled Then AB_CacheCount_Change Me.Name, 1
			Case "String"
				AB.Fso.CreateFile FilePath, o_value
				If CountEnabled Then AB_CacheCount_Change Me.Name, 1
			Case Else
				AB.Error.Msg = "("""&AB.C.HtmlEncode(Me.Name)&""")" : AB.Error.Raise 93
		End Select
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache(cacheName).Remove 方法
	'# @syntax: AB.Cache(cacheName).Remove
	'# @alias:  AB.Cache.Item(cacheName).Remove
	'# @return: 无返回值
	'# @dowhat: 删除文件缓存
	'# 将名称为 cacheName 的文件缓存数据删除。
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache("test").Save
	'# AB.Cache("test").Remove
	'------------------------------------------------------------------------------------------

	Public Sub Remove
		If Not AB.C.Test(DelPath,"[*?]") Then
			If AB.Fso.IsExists(DelPath) Then AB.Fso.Del DelPath
			If CountEnabled Then AB_CacheCount_Change Me.Name, -1
		Else
			AB.Fso.DelFile left(DelPath,len(DelPath)-Len(FileType))
			AB.Fso.DelFolder left(DelPath,len(DelPath)-Len(FileType))
			If CountEnabled Then AB_CacheCount_Change Me.Name, -1
		End If
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache(cacheName).RemoveApp 方法
	'# @syntax: AB.Cache(cacheName).RemoveApp
	'# @alias:  AB.Cache.Item(cacheName).RemoveApp
	'# @return: 无返回值
	'# @dowhat: 删除内容缓存
	'# 将名称为 cacheName 的内容缓存数据删除。
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache("test").SaveApp
	'# AB.Cache("test").RemoveApp
	'------------------------------------------------------------------------------------------

	Public Sub RemoveApp
		If AB.C.Has(Me.Name) Then AB.C.RemoveApp Me.Name
		If CountEnabled Then AB_CacheCount_Change Me.Name, -1
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Cache(cacheName).Del 方法
	'# @syntax: AB.Cache(cacheName).Del
	'# @alias:  AB.Cache.Item(cacheName).Del
	'# @return: 无返回值
	'# @dowhat: 删除某个缓存(包括内容缓存和文件缓存)
	'# 将名称为 cacheName 的内容缓存和文件缓存数据删除。
	'--DESC------------------------------------------------------------------------------------
	'# @param: 无参数
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Cache("test") = "缓存数据"
	'# AB.Cache("test").SaveApp
	'# AB.Cache("test").Del
	'------------------------------------------------------------------------------------------

	Public Sub Del
		Me.Remove
		Me.RemoveApp
	End Sub

	Public Property Get FilePath()
		FilePath = TransPath("[\\:""*?<>|\f\n\r\t\v\s]")
	End Property

	Private Function DelPath()
		DelPath = TransPath("[\\:""<>|\f\n\r\t\v\s]")
	End Function

	Private Function TransPath(ByVal fe)
		Dim s_p : s_p = ""
		Dim parr : parr = split(Me.Name,"/")
		Dim i
		for i = 0 to UBound(parr)
			If AB.C.Test(parr(i),fe) Then parr(i)=Server.URLEncode(parr(i))
			s_p = s_p & "_" & parr(i)
			If i < UBound(parr) Then
				s_p = s_p & "\"
			End If
		next
		If s_p="" Then s_p="_"
		TransPath = SavePath & s_p & FileType
	End Function

	Public Function Ready()
		Dim app : app = AB.C.GetApp(Me.Name)
		Ready = False
		If IsArray(app) Then
			If UBound(app) = 1 Then
				If IsDate(app(0)) Then
					Ready = isValid(app(0))
					If Ready Then Exit Function
				End If
			End If
		End If
		If AB.Fso.IsFile(FilePath) Then
			Ready = isValid(AB.Fso.GetAttr(FilePath,1))
		End If
	End Function

	Private Function isValid(ByVal t)
		If IsDate(t) Then
			If AB.C.Has(d_exp) Then
				isValid = (DateDiff("s",Now,d_exp) > 0)
			Else
				isValid = (DateDiff("s",t,Now) < i_exp*60)
			End If
		End If
	End Function

End Class
%>